home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / xdme_1.84_src.lha / XDME / Src / Mod / Macros.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-03  |  11.2 KB  |  449 lines

  1. /******************************************************************************
  2.  
  3.     MODUL
  4.     lowlevelmacros.c
  5.  
  6.     DESCRIPTION
  7.     die schnittstelle zu den wichtigsten Macro-funktionen,
  8.     die von anderen Moduln verwendet werden duerfen.
  9.  
  10.     NOTES
  11.     dies ist nur ein Dummy - Modul, das zwar alle
  12.     Funktionen exportiert, die beschrieben wurden,
  13.     ihre Realisierung ist jedoch stark eingeschraenkt,
  14.     sie sind auf einfache Strings zurueckgeschraubt,
  15.     so dass die sie verwendenden Moduln wie vorher
  16.     angesprochen werden koennen.
  17.  
  18.     BUGS
  19.  
  20.     TODO
  21.     bei Gelegenheit sollte dieses Modul komplett neu geschrieben werden
  22.     und mit alias.c und main.c neu abgestimmt werden
  23.     (so dass main.c callmacro verwendet neque vero do_command)
  24.  
  25.     EXAMPLES
  26.  
  27.     SEE ALSO
  28.  
  29.     AUTHOR
  30.     Bernd "0" Noll (b_noll@informatik.uni-kl.de)
  31.  
  32.     HISTORY
  33.     10-08-94 null added *simptr, created/updated docs
  34.     21-09-94 b_noll added DEFCMD/DEFHELP-support
  35.     24-09-94 b_noll usage of std_writefile
  36.     01-10-94 b_noll introduced DEFMESSAGE
  37.  
  38. ******************************************************************************/
  39.  
  40. /**************************************
  41.         Includes
  42. **************************************/
  43. /* #include "defs.h" */
  44.  
  45. #include <proto/exec.h>
  46. #include <exec/memory.h>
  47.  
  48. #include <stdio.h>
  49. #include "lists.h"
  50. #include "xdme_base.h"
  51.  
  52. /**************************************
  53.         Globale Variable
  54. **************************************/
  55. Prototype UBYTE * GetArg      (int);
  56. Prototype UBYTE * CommandName (void);
  57.  
  58.  
  59. Prototype void clear_record    (void);
  60. Prototype void start_recording    (void);
  61. Prototype void end_recording    (void);
  62. Prototype void replay_record    (void);
  63. Prototype void do_saverecord    (void);
  64. Prototype void add_record    (char * string);
  65. Prototype void do_simptr    (void);
  66.  
  67.     DEFFLAG( 94-12-03, MacroRecord, 0 )
  68.  
  69. /**************************************
  70.       Interne Defines & Strukturen
  71. **************************************/
  72. #define    simptr(x,y)   do{        \
  73.                 Mx=x;   \
  74.                 My=y;   \
  75.             }while(0)
  76. #define presimptr(px,py) do{        \
  77.                *(px)=Mx;\
  78.                *(py)=My;\
  79.             }while(0)
  80.  
  81. /**************************************
  82.         Interne Variable
  83. **************************************/
  84. /* static char tempmacro_buffer[MAXLINELEN]; */
  85.  
  86.  
  87. /**************************************
  88.        Interne Prototypes
  89. **************************************/
  90. #if 0
  91. void simptr    (WORD  px, WORD  py);
  92. void presimptr (WORD *px, WORD *py);
  93. #endif
  94. extern WORD Mx, My;
  95.         /***********************************************
  96.         ***********************************************
  97.  
  98.         Dies ist lediglich eine Uebergangsloesung,
  99.         solange wir alias.c und main.c noch nicht
  100.         umgeschrieben haben
  101.  
  102.         ***********************************************
  103.         ***********************************************/
  104.  
  105.  
  106.  
  107.  
  108. UBYTE * CommandName (void)
  109. {
  110.     return (av[0]);
  111. } /* CommandName */
  112.  
  113. UBYTE * GetArg (int num)
  114. {
  115.     return(av[num]);
  116. } /* GetArg */
  117.  
  118.  
  119.  
  120.  
  121. /*
  122. **  MACRO RECORDER
  123. **    we can record one input - sequence and replay it
  124. **    we also can save it to a file and are able to source
  125. **    that file as a normal macro-script
  126. **
  127. **    there are 7 functions:
  128. **
  129. **  recording
  130. **    int Start_recording (void)
  131. **    int add_record        (char * string)
  132. **    int end_recording   (void)
  133. **  10-08-94 added
  134. **    void presimptr        (WORD *px, WORD *py);
  135. **
  136. **  playing
  137. **    int replay_record   (void)
  138. **  10-08-94 added
  139. **    void simptr        (WORD px, WORD py);
  140. **
  141. **  saving
  142. **    int save_record     (FILE * fo)
  143. **        (can be read via "source")
  144. **
  145. */
  146.  
  147. static struct MinList record =    /* list to contain the macros */
  148. {
  149.     (struct MinNode *)&record.mlh_Tail, NULL,
  150.     (struct MinNode *)&record.mlh_Head
  151. };
  152. static WORD          record_replaying     = 0;              /* security to avoid endless loops */
  153.  
  154. struct LongNode {
  155.     struct MinNode node;
  156.     WORD       x,
  157.            y;
  158.     char       com[1];
  159. };
  160.  
  161. /*
  162. ** clear_record
  163. **  !this function _MUST_ be called at Program exit!
  164. * ! >CLEARRECORD
  165. * !
  166. * !  clear the previously recorded macro
  167. * !  (this command won't display an error,
  168. * ! if there was no macro recorded)
  169. * !
  170. */
  171. void clear_record (void)
  172. {
  173.     struct LongNode * ln;
  174.  
  175.     while ((ln = (struct LongNode *)RemHead ((struct List *)&record))) {
  176.     FreeMem (ln, sizeof (struct LongNode) + strlen (ln->com));
  177.     } /* while */
  178. } /* clear_record */
  179.  
  180. /*
  181. ** start_recording
  182. *! >RECSTART
  183. *!
  184. *!  invoke the macro recorder;
  185. *!  as long as the macro recorder is active, all
  186. *!  "level-1" commands are stored.
  187. *!  the recording process can be broken
  188. *!  by calling "RECEND" (see there)
  189. * !  or by pressing Ctl-C.
  190. * !  (please note, that sometimes Ctl-C might be
  191. * !  captured by loops or other breakable commands,
  192. * !  before reaching the recorder)
  193. *!
  194. */
  195. /*DEFHELP #cmd record RECSTART - start macro recording */
  196.  
  197. DEFUSERCMD("recstart", 0, CF_VWM|CF_ICO|CF_COK, void, start_recording, (void),)
  198. {
  199.     if (!record_replaying) {
  200.     if (MacroRecord == 0) {
  201.         clear_record();
  202.     } /* if */
  203.  
  204.     MacroRecord ++;
  205.     } else {
  206. DEFMESSAGE( _REC_recorder_started_twice, "%s:\nYou can NOT start recording,\nwhile You are replaying a record" )
  207.     error (_REC_recorder_started_twice, av[0]);
  208.     } /* if */
  209. } /* start_recording */
  210.  
  211. /*
  212. ** end_recording
  213. *! >RECEND
  214. *!
  215. *!  Terminate the macro-recorder;
  216. */
  217. /*DEFHELP #cmd record RECEND - end macro recording */
  218.  
  219. DEFUSERCMD("recend", 0, CF_VWM|CF_ICO|CF_COK, void, end_recording, (void),)
  220. {
  221.     if (MacroRecord) {
  222.     MacroRecord --;
  223.  
  224.     {
  225.         char ab = IS_ABORTED();
  226. DEFMESSAGE( _REC_recorder_ended, "recorder ended!" )
  227.         error (_REC_recorder_ended);
  228.         SET_ABORTION( ab );
  229.     }
  230.  
  231. #    ifdef NOT_DEF
  232.         /* strenggenommen muessten wir zuallererstden recorderend aus dem letzten string herausfiltern */
  233.         /* was aber, wenn der nicht als command sondern als macro kam ??? */
  234.         if (MacroRecord == ~0) {
  235.         struct LongNode * ln;
  236.         if (ln = (struct LongNode *)RemTail ((struct List *)&record)) {
  237.             strcpy (tmp_buffer, ln->com);
  238.  
  239.             ...
  240.         } /* if */
  241.         } /* if */
  242. #    endif
  243.  /* } else if (!record_replaying) { */
  244.      /* ---- as long as we cannot delete endrecording from our last recorder */
  245.      /*      line, we cannot display an error, if we encounter end_recording */
  246.      /* error ("%s:\nYou can NOT end recording,\nif You are NOT recording", av[0]); */
  247.     } /* if */
  248. } /* end_recording */
  249.  
  250. /*
  251. ** add_record:
  252. **  add a string to the recorded macro
  253. **
  254. */
  255. void add_record (char * string)
  256. {
  257.     if (!record_replaying) {
  258.     struct LongNode * ln;
  259.  
  260.     if ((ln = AllocMem (sizeof (struct LongNode) + strlen (string), MEMF_ANY))) {
  261.         strcpy (ln->com, string);
  262.         presimptr (&ln->x, &ln->y);
  263.         AddTail ((struct List *)&record, (struct Node *)ln);
  264.     } else {
  265.         nomemory ();     /* we should NOT abort - we have to execute commands, too */
  266.     } /* if */
  267.  
  268.     //if (breakcheck()) {  /* that way we might have a sure record-terminator - the CTL-C signal */
  269.     //    end_recording ();
  270.     //} /* if */
  271.     } /* if */
  272. } /* add_record */
  273.  
  274. /*
  275. *! >RECPLAY
  276. *!
  277. *!  Replay the previously recorded macro
  278. *!
  279. */
  280. /*DEFHELP #cmd record RECPLAY - replay previously recorded macro */
  281.  
  282. DEFUSERCMD("recplay", 0, CF_VWM|CF_ICO|CF_COK, void, replay_record, (void),)
  283. {
  284.     if (record_replaying) {
  285. DEFMESSAGE( _REC_no_double_action, "%s:\nYou can NOT start replaying a record,\nwhile You are already replaying it" )
  286.     error (_REC_no_double_action, av[0]);
  287.     return;
  288.     } /* if already replaying */
  289.  
  290.     if (MacroRecord) {
  291. DEFMESSAGE( _REC_replay_in_record, "%s:\nYou can NOT start replaying a record,\nwhile You are recording it" )
  292.     error (_REC_replay_in_record, av[0]);
  293.     return;
  294.     } /* if */
  295.  
  296.     if (GetHead (&record)) {
  297.     char * buffer;
  298.     /* We use a run-time allocated buffer */
  299.     if (!(buffer = AllocMem (MAXLINELEN, MEMF_ANY))) {
  300.         nomemory ();     /* error() NEEDS memory for itself */
  301.         /* SET_ABORTION( 1 ); */
  302.         return;
  303.     } else {
  304.         struct LongNode * ln;
  305.  
  306.         for (ln = GetHead (&record); ln; ln = GetSucc (ln)) {
  307.         strncpy (buffer, ln->com, MAXLINELEN-1);
  308.  
  309.         simptr(ln->x, ln->y);
  310.         do_command (buffer);
  311.  
  312.         /* You can NOT terminate Your record by errors */
  313.         clearbreaks ();
  314.  
  315.         /* You can break Your record by pressing Ctrl-C */
  316.         if (breakcheck ()) {
  317.             SET_ABORTION( 1 );
  318.             break;
  319.         } /* if */
  320.         } /* for */
  321.  
  322.         FreeMem (buffer, MAXLINELEN);
  323.     } /* if alloced */
  324.     } /* if ex macro */
  325. } /* replay_record */
  326.  
  327. /*
  328. **  save a recorder macro as a script.
  329. */
  330. int save_record (FILE * fo)
  331. {
  332.     if (fo) {
  333.     struct LongNode * ln;
  334.     for (ln = GetHead (&record); ln; ln = GetSucc (ln)) {
  335.         if ((ln->com[0] == '\'') && !(ln->com[2]))
  336.         sprintf (tmp_buffer, "%s\n", ln->com);
  337.         else
  338.         sprintf (tmp_buffer, "simptr %d %d\n%s\n", (int)ln->x, (int)ln->y, ln->com);
  339.         if (fputs (tmp_buffer, fo) < 0) {
  340. DEFMESSAGE( _REC_write_error, "%s:\nError while writing the\ncurrent record!" )
  341.         error (_REC_write_error, av[0]);
  342.         break;
  343.         } /* if */
  344.     } /* for */
  345.     } /* if */
  346.     return 1;
  347. } /* save_record */
  348.  
  349. /*
  350. *! >RECSAVE filename
  351. *!
  352. *!  save a previously recorded macro as a XDME
  353. *!  scripting file. The file can be read w/
  354. *!  SOURCE (see there)
  355. *!
  356. */
  357. /*DEFHELP #cmd record RECSAVE file - save previously recorded macro to a file. Execute with @{B}SOURCE@{UB} */
  358.  
  359. DEFUSERCMD("recsave", 1, CF_VWM|CF_ICO|CF_COK, void, do_saverecord, (void),)
  360. {
  361.     if (!GetHead (&record)) {
  362. DEFMESSAGE( _REC_save_no_record, "%s:\nCan not save a record,\n if there is NO record!" )
  363.     error (_REC_save_no_record, av[0]);
  364.     } else {
  365.     std_writefile ((int (*) (FILE *, APTR))save_record, NULL);
  366.     } /* if */
  367. } /* do_saverecord */
  368.  
  369.  
  370.  
  371. /*
  372. *! >SIMPTR x y
  373. *!
  374. *!  tell XDME the mousepointer is at another position than
  375. *!  it really is; That command is needed for XDME to execute
  376. *!  scripts which are generated w/ RECSAVE, since it is
  377. *!  necessary that XDME knows where to go on a TOMOUSE;
  378. *!
  379. **  User should NEVER call that function, unless [s]he does
  380. **  really know, what [s]he is doing, since SIMPTR does not
  381. **  just set the pointer to a specified position, but might
  382. **  expect its arguments be positive Window - line/column
  383. **  values; (please look into the source for further information)
  384. **
  385. */
  386. /*DEFHELP #cmd record SIMPTR x y - simulate the mousemovement to windowpos x/y (pixels); that command is needed to replay saved macros, it is not helpful in any other situation */
  387.  
  388. DEFUSERCMD("simptr", 2, CF_VWM|CF_COK, void, do_simptr, (void),)
  389. {
  390.     simptr( atoi(av[1]), atoi(av[2]) );
  391. } /* do_simptr */
  392.  
  393.  
  394.  
  395.  
  396. /******************************************************************************
  397. *****  ENDE macros.c
  398. ******************************************************************************/
  399.  
  400. #if 0
  401. /*
  402. **  calculate the line/column (of the window)
  403. **  that is represented by Mx/My (the internal Mouse Position)
  404. */
  405. void  presimptr (WORD *px, WORD *py) {
  406.     WORD cx, cy;
  407.     extern WORD Mx, My;
  408.  
  409.     /* ---- This is a copy of do_tomouse calculation part from here ... */
  410.     cx = (Mx-Xbase);
  411.     if (cx >= 0) {
  412.     if (cx < Xpixs) cx /= Xsize;
  413.     else        cx  = -2;
  414.     } else        cx  = -1;
  415.  
  416.     cy = (My-Ybase);
  417.     if (cy >= 0) {
  418.     if (cy < Ypixs) cy /= Ysize;
  419.     else        cy  = -2;
  420.     } else        cy  = -1;
  421.     /* ---- ... up to here; the only Difference is, we are using -2 instead of Columns/Lines */
  422.  
  423.     if (px)
  424.     *px = cx;
  425.     if (py)
  426.     *py = cy;
  427.  
  428. } /* presimptr */
  429.  
  430. /*
  431. **  recalculate the Mouseposition from
  432. **  Window-line/column
  433. */
  434. void simptr (WORD px, WORD py) {
  435.     extern WORD Mx, My;
  436.  
  437.     if (py == -2/* || py > Lines*/)
  438.     py = Lines + 1;
  439.  
  440.     if (px == -2/* || px > Columns*/)
  441.     px = Columns;
  442.  
  443.     My = py * Ysize + Ybase + (Ysize / 4);
  444.     Mx = px * Xsize + Xbase + (Xsize / 4);
  445.  
  446. } /* simptr */
  447. #endif
  448.  
  449.